
/**
 * table表格mixins
 */

import Pagination from '@/components/Pagination'
import ActionButton from '@/components/ActionButton'
import DialogForm from '@/components/DialogForm'
import { deepClone } from '@/utils'
export default {
  components: { Pagination, ActionButton, DialogForm },
  data() {
    return {
      pageTitle: null,
      // 列表加载
      listLoading: true,
      // 列表筛选参数
      listQuery: {
        page: 1,
        limit: 10,
        name: undefined,
        start_time: undefined,
        end_time: undefined,
        sort: 'create_time',
        order: 'desc'
      },
      datePicker: '',
      // 编辑表单，引用组件请在resetForm方法中定义
      dataForm: {},
      // 列表数据
      tableData: {
        total: 1,
        finished: false,
        data: []
      },
      // 表单loading
      dialogFormLoading: false,
      deleteLoading: false,
      dialogStatus: '',
      downloadLoading: false,
      // 当前（创建、编辑）选中的index
      index: -1,
      // 获取了表API
      getListApi: null,
      // 创建API
      createApi: null,
      // 更新API
      updateApi: null,
      // 删除API
      deleteApi: null,
      // 是否执行mixin的created
      mixinCreated: true
    }
  },
  created() {
    // 初始化，mixin的created会优先执行，组件的created之后执行，可以通过修改data中mixinCreated为false不执行该方法，
    if (this.mixinCreated) {
      if (this.pageTitle === null) {
        console.error('该页面未设置pageTitle')
      }
      this.resetForm()
      this.getList()
    }
  },
  methods: {
    handleFilter() {
      // 筛选数据
      this.listQuery.page = 1
      this.getList()
    },
    resetForm() {
      // TODO 重置表单，需要被覆盖
      console.error('请自定义重置表单方法')
    },
    async getList() {
      // TODO 获取table数据，可以被覆盖被实现
      if (this.getListApi === null) {
        console.error('请设置获取table列表数据接口')
        return
      }
      this.listLoading = true
      const { err, res } = await this.getListApi({ query: this.listQuery, fetch_table_data: true })
      if (err === null) {
        this.setTableData(res)
      }
      this.listLoading = false
    },
    setTableData(data) {
      // TODO abstract table数据初始化，可以被覆盖，但大部分情况你不应该覆盖它
      this.tableData = {
        total: data.total,
        data: data.data.map(item => {
          item.deleteVisible = false
          return item
        }),
        finished: Number(data.current_page) === Number(data.last_page)
      }
      this.listQuery.page = Number(data.current_page)
    },
    handleCreate() {
      if (this.createApi === null) {
        console.error('请设置createApi接口')
        return
      }
      if (!this.$refs['dataForm']) {
        console.error('请配置弹框')
        return
      }
      // 弹出添加框，不可覆盖！！！
      this.resetForm()
      this.index = -1
      this.dialogStatus = 'create'
      this.$refs['dataForm'].open()
    },
    getSubmitData() {
      // TODO 重新组装需要提交的表单，大多数情况下，你不需要覆盖此方法
      return this.dataForm
    },
    async createData() {
      // 请求创建Api，不可覆盖！！！
      this.dialogFormLoading = true
      const { err, res } = await this.createApi(this.getSubmitData())
      if (err === null) {
        this.afterCreate(res)
        this.$notify.success({
          title: '成功',
          message: `添加${this.pageTitle}成功`
        })
        this.$refs['dataForm'].close()
      } else {
        this.$notify.error({
          title: '失败',
          message: err
        })
      }
      this.dialogFormLoading = false
    },
    afterCreate(data) {
      // 创建成功后返回操作，根据自定义覆盖，但大部分时候你不需要覆盖它
      this.tableData.data.push({
        ...deepClone(this.dataForm),
        ...data,
        deleteVisible: false
      })
    },
    setDataForm(data) {
      // TODO abstract 编辑时设置表单内容，需要被重写
      this.dataForm = deepClone(data)
    },
    handleUpdate(row, index) {
      if (this.updateApi === null) {
        console.error('请设置updateApi接口')
        return
      }
      // 弹出编辑框，不可覆盖！！！
      if (index < 0) {
        console.error('编辑表单需要传递index参数')
        return
      }
      if (!this.$refs['dataForm']) {
        console.error('请配置弹框')
        return
      }
      this.index = index
      this.dialogStatus = 'update'
      this.setDataForm(row)
      this.$refs['dataForm'].open()
    },
    async updateData() {
      // 更新Api操作，不可覆盖！！！
      this.dialogFormLoading = true
      const { err, res } = await this.updateApi(this.getSubmitData())
      if (err === null) {
        this.afterUpdate(res)
        this.$notify.success({
          title: '成功',
          message: `更新${this.pageTitle}成功`
        })
        this.$refs['dataForm'].close()
      } else {
        this.$notify.error({
          title: '失败',
          message: err
        })
      }
      this.dialogFormLoading = false
    },
    afterUpdate(data) {
      // 更新成功操作， 根据自定义覆盖 但大部分情况你不需要覆盖它
      this.tableData.data.splice(this.index, 1, {
        ...deepClone(this.dataForm),
        ...data
      })
    },
    async handleDelete(row, index) {
      // 处理删除，大部分情况下你不需要覆盖它
      this.deleteLoading = true
      const data = {}
      // 过滤掉非必要参数，防止出现嵌套循环
      Object.keys(row).filter(key => {
        const num = Number(row[key])
        return typeof Number(row[key]) === 'number' && !isNaN(Number(row[key])) && num > 0
      }).forEach(key => {
        data[key] = row[key]
      })
      const { err } = await this.deleteApi(data)
      if (err === null) {
        this.$notify.success({
          title: '成功',
          message: '删除成功'
        })
        row.deleteVisible = false
        this.afterDelete(index)
      }
      this.deleteLoading = false
    },
    afterDelete(index) {
      // 删除后处理，大部分时候你不需要覆盖它
      this.tableData.data.splice(index, 1)
    },
    async handleExport() {
      if (this.listLoading) {
        return
      }
      this.listLoading = true
      const { err, res } = await this.getListApi({ query: this.listQuery, fetch_table_data: true, export_data: true })
      if (err === null) {
        this.handleDownload(res)
      }
    },
    makeExcel() {
      // TODO 制作excel，需要被重写
      const tHeader = ['用户名', '邮箱', '性别', '状态']
      const filterVal = ['user_name', 'user_email', 'gender', 'user_status']
      return [tHeader, filterVal]
    },
    handleDownload(data) {
      // TODO example 待更新
      import('@/vendor/Export2Excel').then(excel => {
        const [tHeader, filterVal] = this.makeExcel()
        const title = this.pageTitle + '_' + Date.now()
        excel.export_json_to_excel2(tHeader, data, filterVal, title)
        this.listLoading = false
      })
    }
  }
}
